/* Copyright © 2010 LPRM
Universidade Federal do Espírito Santo - RNP-GT CWTools

This file is part of GW-Android.

GW-Android is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

GW-Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with GW-Android. If not, see <http://www.gnu.org/licenses/>. */
package br.ufes.cwtools.gw.android.components;

import android.app.Activity;

public abstract class Component extends Activity {
	public static final int RESULT_BACK = RESULT_FIRST_USER;
	public static final String EXTRA_RELATED_COMPONENTS = "br.ufes.cwtools.android.Component.EXTRA_RELATED_COMPONENTS";
	public static final String EXTRA_SELECTED_COMPONENT_TAG = "br.ufes.cwtools.android.Component.EXTRA_SELECTED_COMPONENT_TAG";
	public static final String RELATED_EXTRA_DEFAULT = "default";  // TODO melhorar
	public static final String EXTRA_BASE_URL = "br.ufes.cwtools.android.Component.EXTRA_BASE_URL";
	public static final String EXTRA_APPLICATION_XML = "br.ufes.cwtools.android.extra_application_xml";
	public static final String EXTRA_APPLICATION_URL = "br.ufes.cwtools.android.extra_application_url";
	public static final String EXTRA_ENTITY_CLASS = "br.ufes.cwtools.gw.android.components.Entity.class";
	public static final String EXTRA_ENTITY_ID = "br.ufes.cwtools.gw.android.components.Entity.id";
	public static final String EXTRA_ENTITY_URI = "br.ufes.cwtools.gw.android.components.Entity.uri";
	
	@Override
	public void finish() {
		// Força a seleção do related component que será executado em seguida,
		// a menos que um já tenha sido especificado.
		if (getIntent().getStringExtra(EXTRA_SELECTED_COMPONENT_TAG) == null) {
			selectNextComponentAndFinish(RELATED_EXTRA_DEFAULT);
		} else {
			finish(RESULT_OK);
		}
	}
	
	/**
	 * Método de conveniência para chamar finish() com o parâmetro adequado caso
	 * o component esteja finalizando em decorrência de um erro.
	 */
	protected void fail() {
		finish(RESULT_CANCELED);
	}
	
	protected void finish(int resultCode) {
		setResult(resultCode, getIntent());
		super.finish();
	}
	
	@Override
	public void onBackPressed() {
		finish(RESULT_BACK);
		return;
	}

	//Facilitadores/atalhos
	protected String getConfiguration(String name) {
		return getIntent().getStringExtra(name);
	}
	
	protected String getApplicationUrl(){
		return getIntent().getStringExtra(EXTRA_APPLICATION_URL);
	}
	
	protected String getApplicationXml(){
		return getIntent().getStringExtra(EXTRA_APPLICATION_XML);
	}

	protected String getComponentBaseUrl(){
		return getIntent().getStringExtra(EXTRA_BASE_URL);
	}
	
	// Métodos de conveniência para chamar selectNextComponent() com os parâmetros adequados.
	protected void selectNextComponent(String relatedExtra) {
		selectNextComponent(relatedExtra, false, true);
	}
	
	protected void selectNextComponent(String relatedExtra, boolean isCancelable) {
		selectNextComponent(relatedExtra, false, isCancelable);
	}
	
	protected void selectNextComponentAndFinish(String relatedExtra) {
		selectNextComponent(relatedExtra, true, false);
	}
	
	// TODO Método apenas para testes; não faz sentido permitir que o diálogo seja
	// cancelado quando a activity do componente será finalizada em seguida.
	protected void selectNextComponentAndFinish(String relatedExtra, boolean isCancelable) {
		selectNextComponent(relatedExtra, true, isCancelable);
	}
	
	/**
	 * Determina o component a ser executado em seguida e coloca o extra correspondente
	 * no intent desta activity. Se necessário será exibido um diálogo para que o usuário
	 * escolha qual componente deseja utilizar.
	 * 
	 * @param relatedExtra especifica qual conjunto de related components utilizar.
	 * Se este parâmetro for null serão utilizados os related components especificados como padrão.
	 * @param finishAfterwards indica se este component será finalizado em seguida.
	 * @param isCancelable indica se é permitido ao usuário cancelar o diálogo.
	 */
	private void selectNextComponent(String relatedExtra, final boolean finishAfterwards, boolean isCancelable) {
		ComponentLifecycleHelper.selectNextComponent(this, relatedExtra, finishAfterwards, isCancelable);
	}
}
